package com.wfh.frp.handler;

import com.wfh.frp.model.ProxyMsg;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @Title: ProxyClientHandler
 * @Author wangfenghuan
 * @Package com.wfh.frp.handler
 * @Date 2025/10/8 13:48
 * @description: 客户端处理器
 */
@Slf4j
public class ProxyClientHandler extends SimpleChannelInboundHandler<ProxyMsg> {

    /**
     * 主服务ip
     */
    private final String targethost;

    private final int targetPort;

    /**
     * 连接内网真实的服务
     */
    private volatile Channel serviceChannel;

    public ProxyClientHandler(String targethost, int targetPort) {
        this.targethost = targethost;
        this.targetPort = targetPort;
    }


    /**
     * 收到消息
     * @param channelHandlerContext
     * @param msg
     * @throws Exception
     */
    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, ProxyMsg msg) throws Exception {
        byte type = msg.getType();

        // 处理心跳消息
        if (type == ProxyMsg.HEARTBEAT) {
            log.debug("Received heartbeat from server: {}", channelHandlerContext.channel().id());
            return; // 心跳消息不需要进一步处理
        }

        if (type == ProxyMsg.SERVICE_CONNECT){
            if (serviceChannel == null || !serviceChannel.isActive()){
                // 连接本地服务
                Bootstrap bootstrap = new Bootstrap();
                bootstrap.group(channelHandlerContext.channel().eventLoop())
                        .channel(NioSocketChannel.class)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel socketChannel) throws Exception {
                                socketChannel.pipeline()
                                        .addLast(new ServiceToTargetHandler(channelHandlerContext.channel(), msg.getChannelId()));
                            }
                        });
                ChannelFuture connect = bootstrap.connect(targethost, targetPort);
                connect.addListener((ChannelFutureListener) c -> {
                    if (c.isSuccess()){
                        serviceChannel = c.channel();
                        ProxyMsg proxyMsg = new ProxyMsg();
                        proxyMsg.setType(ProxyMsg.SERVICE_CONNECT);
                        proxyMsg.setChannelId(msg.getChannelId());
                        channelHandlerContext.writeAndFlush(proxyMsg);
                    }
                });
            }
        } else if (type == ProxyMsg.TRANSFER){
            // 来自访客的数据，转发给内网服务
            if (serviceChannel != null && serviceChannel.isActive()){
                serviceChannel.writeAndFlush(msg);
            }
        }
    }

    /**
     * 通道关闭
     * @param ctx
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        if (serviceChannel != null) {
            serviceChannel.close();
        }
    }
}
